import React from "react";
import PropTypes from "prop-types";

class ClassComponent extends React.Component {
  // 设置默认值
  static defaultProps = {
    title: "default title",
  };

  state = {
    num: 0,
  };

  // 属性校验规则
  static propTypes = {
    title: PropTypes.string,
  };

  componentWillMount() {
    // 尽量不要使用这个方法 use componentDidMount or the constructor instead; will stop working in React 17
    console.log("组件挂载： 【将要挂载】componentWillMount");
  }

  componentDidMount() {
    console.log("组件挂载： 【挂载完成】组件第一次加载的时候执行");
  }

  UNSAFE_componentWillReceiveProps() {
    // use static getDerivedStateFromProps
    console.log("父组件更细导致子组件更新");
  }

  shouldComponentUpdate(nextProps, nextState, nextContext) {
    console.log(
      "之前的 props: ",
      this.props,
      " ，之前的 state: ",
      this.state,
      "，之前的 context:",
      this.context
    );

    console.log(
      "最新的 props: ",
      nextProps,
      " ，最新的 state: ",
      nextState,
      " 最新的 上下文 nextContext",
      nextContext
    );

    console.log("组件更新: [是否执行更新】 shouldComponentUpdate");

    return true;
  }

  UNSAFE_componentWillUpdate(nextProps, nextState, nextContext) {
    //  不推荐使用的 生命周期函数，use getSnapshotBeforeUpdate instead
    console.log("组件更新： 【将要更新】UNSAFE_componentWillUpdate");
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("snapshot: ", snapshot);
    console.log("组件更新：【完毕】：componentDidUpdate");
  }

  render() {
    const { title } = this.props;
    const { num } = this.state;
    console.log("组件 render ");

    return (
      <div>
        {num} - {title}
        <br />
        <br />
        <button
          onClick={() => {
            // 标准做法，通过 this.setState(partialState) 来进行更新，这里 setState 会进行 state 合并
            this.setState({
              num: num + 1,
            });
          }}
        >
          标准更新 setState, 会进行 state 合并的
        </button>
        <br />
        <br />
        <button
          onClick={() => {
            // 错误的做法
            this.state.num = num + 1;
          }}
        >
          ❌： 直接修改 state 更新
        </button>
        <br />
        <br />
        <button
          onClick={() => {
            // 不推荐做法
            this.state.num = num + 1;
            this.forceUpdate();
          }}
        >
          不推荐： 通过 this.forceUpdate更新 state （会直接跳过
          shouldComponentUpdate)
        </button>
      </div>
    );
  }
}

export default ClassComponent;
